import * as fs from "fs";
import { decode } from "iconv-lite";
import { detect } from "jschardet";
import { dirname, extname, resolve, sep } from "path";
import { promisify } from "util";

export const readdirAsync = promisify(fs.readdir);
export const readFileAsync = promisify(fs.readFile);

export function readFileSync(path: string): string {
    if (fs.existsSync(path)) {
        let buffer = fs.readFileSync(path);
        if (buffer.length > 0) {
            let info = detect(buffer);
            return decode(buffer, info.encoding);
        }
    }
    return "";
}

export function readFolderFiles(path: string): { path: string, content: string }[] {
    const result: { path: string, content: string }[] = [];
    if (fs.existsSync(path)) {
        let dirents = fs.readdirSync(path, { withFileTypes: true });
        for (const d of dirents) {
            const resolvedPath = resolve(path, d.name);
            if (d.isFile()) {
                result.push({ path: resolvedPath, content: readFileSync(resolvedPath) });
            }
            else if (d.isDirectory()) {
                result.push(...readFolderFiles(resolvedPath));
            }
        }
    }
    return result;
}

export function writeFileText(filePath: string, content: string, encoding: BufferEncoding = "utf8") {
    const folders = filePath.split(sep).slice(0, -1);
    if (folders.length > 0) {
        folders.reduce((prev, folder) => {
            const folderPath = prev + sep + folder;
            if (!fs.existsSync(folderPath)) {
                fs.mkdirSync(folderPath);
            }
            return folderPath;
        });
    }
    fs.writeFileSync(filePath, content, { encoding });
}


export function getFolderFiles(fsPath: string, extens: Set<string>) {
    if (!fs.existsSync(fsPath)) {
        return [];
    }

    let result: string[] = [];

    let directory = fsPath;
    if (fs.statSync(directory).isFile()) {
        directory = dirname(directory);
    }

    let dirents = fs.readdirSync(directory, { withFileTypes: true });
    for (const dirent of dirents) {
        let fullPath = resolve(directory, dirent.name);
        if (dirent.isFile() && extens.has(extname(dirent.name).toLowerCase())) {
            result.push(fullPath);
        }
        else if (dirent.isDirectory()) {
            result.push(...getFolderFiles(fullPath, extens));
        }
    }

    return result;
}
